package com.lu.runner;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.lu.annnoation.After;
import com.lu.annnoation.Before;
import com.lu.annnoation.Test;
import com.lu.testCase.HelloTest;

/**
 * 解析注解，执行测试
 * 
 * @author lusm
 *
 */
public class Runner {
	// 被注解的类
	private Class<?> clazz;
	// 被注解的类的实例
	private Object object;
	// 先执行的方法list
	private List<Method> beforeMethods = new ArrayList<Method>();
	// 后执行的方法list
	private List<Method> afterMethods = new ArrayList<Method>();
	// test的方法list
	private List<Method> testMethods = new ArrayList<Method>();

	/**
	 * 构造类
	 * 
	 * @param clazz
	 */
	public Runner(Class<?> clazz) {
		this.clazz = clazz;
	}

	/**
	 * 执行测试
	 */
	public void doRun() {
		// 获取所有的方法并将他们分别放入各自的集合中
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			AddIntoList(method, beforeMethods, Before.class);
			AddIntoList(method, afterMethods, After.class);
			AddIntoList(method, testMethods, Test.class);
		}
		// 执行各自集合中的方法
		runBefore();
		runTest();
		runAfter();
	}

	/**
	 * 测试前执行的方法
	 */
	private void runBefore() {
		for (Method method : beforeMethods) {
			try {
				object = clazz.newInstance();
				method.invoke(object, new Object[] {});
				System.out.println("test before-----------");
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 测试后执行的方法
	 */
	private void runAfter() {
		for (Method method : afterMethods) {
			try {
				method.invoke(object, new Object[] {});
				System.out.println("test after-----------");
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 测试方法
	 */
	private void runTest() {
		for (Method method : testMethods) {
			try {
				System.out.println("testing -----------");
				method.invoke(object, new Object[] {});
				System.out.println("testing -----------");
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * 查看method是不是被clazz注解，如果是，就把他加入到list中
	 * 
	 * @param method 测试类中的方法
	 * @param list
	 * @param clazz 注解类
	 */
	private void AddIntoList(Method method, List<Method> list, Class<? extends Annotation> clazz) {
		if (method.isAnnotationPresent(clazz)) {
			list.add(method);
		}
	}
}
